// 
// 
// 

#include "MorseUtils.h"


char MorseUtils::Decode(unsigned int c, unsigned short len) {
	if (len > maxLen) {
		return '?';
	}
	unsigned short idx = 1;
	for (int i = 0; i < len; i++) {
		int b = ((c >> (len - i - 1)) & 1);
		idx = (2 * idx + 1 * b);
	}
	/*
	Serial.println("idx is ");
	Serial.println(idx);
	Serial.println(this->letters);
	Serial.println(this->letters[idx]);
	*/
	return this->letters[idx];
}

void MorseUtils::Push(unsigned int* code, unsigned short val, unsigned short* len) {
	if (*len > maxLen) {
		*len++;
		return;
	}
	*code = (*code << 1) | val;
	(*len)++;
}

unsigned int MorseUtils::Encode(char c, unsigned short* len) {
	const char* q = strchr(this->letters, c);
	unsigned short idx = q - this->letters;
	int i = 0;
	unsigned int cw = 0;
	while (idx != 1) {
		int t = idx % 2;
		idx = idx / 2;
		cw = (cw | (t << i++));
	}
	*len = i;
}

void MorseUtils::FireDit() {
	this->Push(&this->buffer, 0, &this->bufferLen);
	//Serial.println(this->buffer);
	//Serial.println(this->bufferLen);
}

void MorseUtils::FireDah() {
	this->Push(&this->buffer, 1, &this->bufferLen);
	//Serial.println(this->buffer);
	//Serial.println(this->bufferLen);
}

char MorseUtils::GetRst() {
	//printf("buffer is %d bufferLen is ", this->buffer, this->bufferLen);
	//Serial.println(this->buffer);
	//Serial.println(this->bufferLen);
	if (this->bufferLen == 0) {
		return 0;
	}
	//Serial.println(this->buffer);
	//Serial.println(this->bufferLen);
	char ret = this->Decode(this->buffer, this->bufferLen);
	//Serial.print("ret is ");
	//Serial.println(ret);
	this->buffer = 0;
	this->bufferLen = 0;
	return ret;
}
